From c75e9c1df7ecb9a7c4bb517067a0a4e3a282f61c Mon Sep 17 00:00:00 2001 From: Cody Russell Date: Mon, 30 Apr 2007 15:29:16 +0000 Subject: [PATCH] Clear correct area svn path=/trunk/; revision=17737 --- ChangeLog | 8 ++ gdk/win32/gdkwindow-win32.c | 150 +++++++++++++++++++++++++++++++++++- 2 files changed, 154 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3db567bca6..67e5ab1d59 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2007-04-30 Cody Russell + + * gdk/win32/gdkwindow-win32.c: Reintroduced erase_background(), + but now we're calling it from _gdk_windowing_window_clear_area() + instead of from the WM_ERASEBKGND event. Also fixes the area + that is cleared so that it is not an extra row and column too + large. (Neil Roberts, #415681) + 2007-04-30 Matthias Clasen * gtk/gtktextview.c: Allow indents to be negative. (#Bug 434308) diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c index 75d944d2d7..631d4200d1 100644 --- a/gdk/win32/gdkwindow-win32.c +++ b/gdk/win32/gdkwindow-win32.c @@ -1402,6 +1402,139 @@ gdk_window_reparent (GdkWindow *window, _gdk_window_init_position (GDK_WINDOW (window_private)); } +static void +erase_background (GdkWindow *window, + HDC hdc) +{ + HDC bgdc = NULL; + HBRUSH hbr = NULL; + HPALETTE holdpal = NULL; + RECT rect; + COLORREF bg; + GdkColormap *colormap; + GdkColormapPrivateWin32 *colormap_private; + int x, y; + int x_offset, y_offset; + + if (((GdkWindowObject *) window)->input_only || + ((GdkWindowObject *) window)->bg_pixmap == GDK_NO_BG || + GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->position_info.no_bg) + { + return; + } + + colormap = gdk_drawable_get_colormap (window); + + if (colormap && + (colormap->visual->type == GDK_VISUAL_PSEUDO_COLOR || + colormap->visual->type == GDK_VISUAL_STATIC_COLOR)) + { + int k; + + colormap_private = GDK_WIN32_COLORMAP_DATA (colormap); + + if (!(holdpal = SelectPalette (hdc, colormap_private->hpal, FALSE))) + WIN32_GDI_FAILED ("SelectPalette"); + else if ((k = RealizePalette (hdc)) == GDI_ERROR) + WIN32_GDI_FAILED ("RealizePalette"); + else if (k > 0) + GDK_NOTE (COLORMAP, g_print ("erase_background: realized %p: %d colors\n", + colormap_private->hpal, k)); + } + + x_offset = y_offset = 0; + while (window && ((GdkWindowObject *) window)->bg_pixmap == GDK_PARENT_RELATIVE_BG) + { + /* If this window should have the same background as the parent, + * fetch the parent. (And if the same goes for the parent, fetch + * the grandparent, etc.) + */ + x_offset += ((GdkWindowObject *) window)->x; + y_offset += ((GdkWindowObject *) window)->y; + window = GDK_WINDOW (((GdkWindowObject *) window)->parent); + } + + if (GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->position_info.no_bg) + { + /* Improves scolling effect, e.g. main buttons of testgtk */ + return; + } + + GetClipBox (hdc, &rect); + + if (((GdkWindowObject *) window)->bg_pixmap == NULL) + { + bg = _gdk_win32_colormap_color (GDK_DRAWABLE_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->colormap, + ((GdkWindowObject *) window)->bg_color.pixel); + + if (!(hbr = CreateSolidBrush (bg))) + WIN32_GDI_FAILED ("CreateSolidBrush"); + else if (!FillRect (hdc, &rect, hbr)) + WIN32_GDI_FAILED ("FillRect"); + if (hbr != NULL) + DeleteObject (hbr); + } + else if (((GdkWindowObject *) window)->bg_pixmap != GDK_NO_BG) + { + GdkPixmap *pixmap = ((GdkWindowObject *) window)->bg_pixmap; + GdkPixmapImplWin32 *pixmap_impl = GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl); + + if (x_offset == 0 && y_offset == 0 && + pixmap_impl->width <= 8 && pixmap_impl->height <= 8) + { + if (!(hbr = CreatePatternBrush (GDK_PIXMAP_HBITMAP (pixmap)))) + WIN32_GDI_FAILED ("CreatePatternBrush"); + else if (!FillRect (hdc, &rect, hbr)) + WIN32_GDI_FAILED ("FillRect"); + if (hbr != NULL) + DeleteObject (hbr); + } + else + { + HGDIOBJ oldbitmap; + + if (!(bgdc = CreateCompatibleDC (hdc))) + { + WIN32_GDI_FAILED ("CreateCompatibleDC"); + return; + } + if (!(oldbitmap = SelectObject (bgdc, GDK_PIXMAP_HBITMAP (pixmap)))) + { + WIN32_GDI_FAILED ("SelectObject"); + DeleteDC (bgdc); + return; + } + x = -x_offset; + while (x < rect.right) + { + if (x + pixmap_impl->width >= rect.left) + { + y = -y_offset; + while (y < rect.bottom) + { + if (y + pixmap_impl->height >= rect.top) + { + if (!BitBlt (hdc, x, y, + pixmap_impl->width, pixmap_impl->height, + bgdc, 0, 0, SRCCOPY)) + { + WIN32_GDI_FAILED ("BitBlt"); + SelectObject (bgdc, oldbitmap); + DeleteDC (bgdc); + return; + } + } + y += pixmap_impl->height; + } + } + x += pixmap_impl->width; + } + SelectObject (bgdc, oldbitmap); + DeleteDC (bgdc); + } + } +} + void _gdk_windowing_window_clear_area (GdkWindow *window, gint x, @@ -1428,8 +1561,8 @@ _gdk_windowing_window_clear_area (GdkWindow *window, GDK_WINDOW_HWND (window), width, height, x, y)); hdc = GetDC (GDK_WINDOW_HWND (window)); - IntersectClipRect (hdc, x, y, x + width + 1, y + height + 1); - SendMessageW (GDK_WINDOW_HWND (window), WM_ERASEBKGND, (WPARAM) hdc, 0); + IntersectClipRect (hdc, x, y, x + width, y + height); + erase_background (window, hdc); GDI_CALL (ReleaseDC, (GDK_WINDOW_HWND (window), hdc)); } } @@ -1445,6 +1578,7 @@ _gdk_windowing_window_clear_area_e (GdkWindow *window, if (!GDK_WINDOW_DESTROYED (window)) { + HDC hdc; RECT rect; GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area_e: %p: " @@ -1452,10 +1586,18 @@ _gdk_windowing_window_clear_area_e (GdkWindow *window, GDK_WINDOW_HWND (window), width, height, x, y)); + /* The background should be erased before the expose event is + generated */ + hdc = GetDC (GDK_WINDOW_HWND (window)); + IntersectClipRect (hdc, x, y, x + width, y + height); + erase_background (window, hdc); + GDI_CALL (ReleaseDC, (GDK_WINDOW_HWND (window), hdc)); + rect.left = x; - rect.right = x + width + 1; + rect.right = x + width; rect.top = y; - rect.bottom = y + height + 1; + rect.bottom = y + height; + GDI_CALL (InvalidateRect, (GDK_WINDOW_HWND (window), &rect, TRUE)); UpdateWindow (GDK_WINDOW_HWND (window)); } -- 2.30.2